package it.edgeworks.dsession.impl.memcache;

import java.util.Date;
import java.util.Map;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;

import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.danga.MemCached.MemCachedClient;
import com.thoughtworks.xstream.XStream;

import it.edgeworks.dsession.api.HttpSessionProviderBase;

/**
 * @author Ivan Diana
 * @version $Revision: 1 $
 */
public class HttpSessionProviderImpl extends HttpSessionProviderBase {

    private MemCachedClient cacheClient;

    protected final Log logger = LogFactory.getLog(getClass());

    public void init(FilterConfig config) throws ServletException {
        super.init(config);

        String clientClassName = config.getInitParameter("cache-client-class");
        String configFileName = config.getInitParameter("cache-client-config");
        try {
            this.cacheClient = (SimpleCacheClient) Class.forName(clientClassName).getConstructor(String.class).newInstance(configFileName);
        } catch (Exception e) {
            logger.error("Can't load memchace client:" + e.getLocalizedMessage());
            e.printStackTrace();
        }
    }

    public boolean loadSession(String sessionId, HttpSession session) {
        //System.out.println(new Date() + " - load session 1");
        boolean loadedSession = false;
        //System.out.println(new Date() + " - load session 2");
        byte[] serializedSession = (byte[]) this.cacheClient.get(sessionId);
        //System.out.println(new Date() + " - load session 3");
        if (serializedSession != null) {
            //System.out.println(new Date() + " - load session 4");
            XStream xstream = new XStream();
            //System.out.println(new Date() + " - load session 5");
            // Questa è l'operazione più onerosa, più dati ci sono in sessione più aumenta il tempo di elaborazione
            Map sessAttrib = (Map) xstream.fromXML(new ByteArrayInputStream(serializedSession));
            //System.out.println(new Date() + " - load session 6");
            //logger.debug("loading map attrib from repository:" + sessAttrib);            
            map2session(sessAttrib, session);
            //System.out.println(new Date() + " - load session 7");
            loadedSession = true;
        }
        //System.out.println(new Date() + " - load session 8");
        return loadedSession;
    }

    public void saveSession(String sessionId, HttpSession session) {
        try {
            //System.out.println(new Date() + " - saving session 1");
            Map<String, Object> sessAttrib = session2Map(session);
            //System.out.println(new Date() + " - saving session 2");
            XStream xstream = new XStream();
            //System.out.println(new Date() + " - saving session 3");
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            //System.out.println(new Date() + " - saving session 4");
            xstream.toXML(sessAttrib, os);
            //System.out.println(new Date() + " - Start saving session to memecache server:" + sessionId);
            this.cacheClient.set(sessionId, os.toByteArray(), getExpireDatetime(timeoutInSeconds));
            //System.out.println(new Date() + " - End saving session from memecache server:" + sessionId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void destroy() {
    }

}
